package com.gitee.wsl.ext.string

import kotlin.jvm.JvmName

fun String.quoted(): Boolean = this.startsWith('"') && this.endsWith('"')

fun String.isQuoted(): Boolean = this.startsWith('"') && this.endsWith('"')

fun String.unquote(): String =
    if (isQuoted()) this.substring(1, this.length - 1).unescape() else this

internal fun String.unescape(): String {
    val out = StringBuilder()
    var n = 0
    while (n < this.length) {
        val c = this[n++]
        when (c) {
            '\\' -> {
                val c2 = this[n++]
                when (c2) {
                    '\\' -> out.append('\\')
                    '"' -> out.append('\"')
                    'n' -> out.append('\n')
                    'r' -> out.append('\r')
                    't' -> out.append('\t')
                    'u' -> {
                        val chars = this.substring(n, n + 4)
                        n += 4
                        out.append(chars.toInt(16).toChar())
                    }
                    else -> {
                        out.append("\\$c2")
                    }
                }
            }
            else -> out.append(c)
        }
    }
    return out.toString()
}


/**
 * Add quotes to this string, if not present. Will do nothing to `null`s.
 *
 * Will turn :
 * * `foo` -> `"foo"`,
 * * `"foo"` -> `"foo"` (no change)
 * * `null` -> `null` (no change)
 */
@get:JvmName("quotedOrNull")
inline val String?.quoted: String? get() = this?.quoted

/**
 * Add quotes to this string, if not present.
 *
 * Will turn :
 * * `foo` -> `"foo"`,
 * * `"foo"` -> `"foo"` (no change)
 */
inline val String.quoted: String get() = """"${removeSurrounding("\"")}""""

fun String.removeFirstAndEndQuotes(from: Int = 0) =
    substring(from).replace("^([\"'])(.*?)\\1?$".toRegex(), "$2").trim('\'', '"')